#pragma once

#include <assert.h>
#include <fstream>
#include <vector>

// Reqires string library
class String;

/*
	File access (Work in progress)
		Wrapper class for writing information to a file
 */
class FileAccess
{
public:	// Constructor / Destructor
	FileAccess();
	~FileAccess();

public: // Filename Setup, Loading, Saving and Streaming Functions
	bool OpenFile( const char* filename, bool directWrite = false, bool binary = true, bool ascii = true );
	void Close();

	void LoadFromFile(bool binary = true);		// Reload all file access contents from either binary or ascii format
	void SaveToFile();							// Save all file access contents

public: // Properties

	bool			IsDirectWrite()	{ return m_isDirectWrite;	}
	bool			IsOpen()		{ return m_isOpen;			}
	const char*		BinaryFile()	{ return m_binaryFile;		}
	const char*		AsciiFile()		{ return m_asciiFile;		}


public: // Public Accessor Functions

	// Returns the length in bytes of all of the currently stored values
	unsigned int GetBinarySize();

	void WriteByte(				unsigned char	value, const char* name = 0);
	void WriteBytes(			const void*		bytes, unsigned int length, const char* name = 0);
	
	void WriteChar(				char			value, const char* name = 0);
	void WriteShort(			short			value, const char* name = 0);
	void WriteUnsignedShort(	unsigned short	value, const char* name = 0);
	void WriteLong(				long			value, const char* name = 0);
	void WriteUnsignedLong(		unsigned long	value, const char* name = 0);
	void WriteInteger(			int				value, const char* name = 0);
	void WriteUnsignedInt(		unsigned int	value, const char* name = 0);
	void WriteFloat(			float			value, const char* name = 0);
	void WriteDouble(			double			value, const char* name = 0);


	void ReadBytes(				void*			bytes, unsigned int length );

	unsigned char	ReadByte();
	char			ReadChar();
	short			ReadShort();
	unsigned short	ReadUnsignedShort();
	long			ReadLong();
	unsigned long	ReadUnsignedLong();
	int				ReadInteger();
	unsigned int	ReadUnsignedInt();
	float			ReadFloat();
	double			ReadDouble();

	String			ReadLine();

public:

	bool			EndOfFile(bool binary);

public: // Overloaded Operators
	void operator+=(	unsigned char	value ) { WriteByte(value);				}
	void operator+=(	char			value ) { WriteChar(value);				}
	void operator+=(	short			value ) { WriteShort(value);			}
	void operator+=(	unsigned short	value ) { WriteUnsignedShort(value);	}
	void operator+=(	long			value ) { WriteLong(value);				}
	void operator+=(	unsigned long	value ) { WriteUnsignedLong(value);		}
	void operator+=(	int				value ) { WriteInteger(value);			}
	void operator+=(	unsigned int	value ) { WriteUnsignedInt(value);		}
	void operator+=(	float			value ) { WriteFloat(value);			}
	void operator+=(	double			value ) { WriteDouble(value);			}
	
private: // Private Member Functions

	void demandExist(	const char* filename );
	void setAscii(		const char* str, int len = 0 );
	void setBin(		const char* str, int len = 0 );
	void getAsciiFile(	const char* filename );

private: // Data Storage
	
	bool			m_isDirectWrite;		// If we should write directly to the file or not
	bool			m_isOpen;				// If we currently have any file pointers open

	bool			m_openBinary;			// If we are to open for read/write the binary file
	bool			m_openAscii;			// If we are to open for read/write the ascii file
	bool			m_readBinary;			// If we should read from the binary or ascii file
	
	char*			m_binaryFile;			// Full binary file name with path
	char*			m_asciiFile;			// Full ascii file name with path
	

	std::fstream	m_asciiFileStream;		// Input and output ASCII filestream
	std::fstream	m_binaryFileStream;		// Input and output binary filestream

};


